package com.blog.cmrpersonalblog.controller;

import cn.dev33.satoken.annotation.SaCheckRole;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.blog.cmrpersonalblog.common.Result;
import com.blog.cmrpersonalblog.dto.article.request.ArticleTagCreateRequest;
import com.blog.cmrpersonalblog.dto.article.request.ArticleTagQueryRequest;
import com.blog.cmrpersonalblog.dto.article.request.ArticleTagUpdateRequest;
import com.blog.cmrpersonalblog.dto.article.response.ArticleTagResponse;
import com.blog.cmrpersonalblog.dto.tag.requset.TagBatchOperationRequest;
import com.blog.cmrpersonalblog.entity.ArticleTag;
import com.blog.cmrpersonalblog.service.ArticleTagRelationService;
import com.blog.cmrpersonalblog.service.TagManagementService;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;

/**
 * 文章标签控制器
 * 提供标签的管理功能，包括CRUD操作、查询、统计等
 */
@Slf4j
@RestController
@RequestMapping("/api/tags")
@CrossOrigin(origins = "*", maxAge = 3600)
@Validated
public class ArticleTagController {

   @Resource
    private TagManagementService tagManagementService;

   @Resource
    private ArticleTagRelationService articleTagRelationService;

    /**
     * 分页查询标签列表
     */
    @GetMapping("/list")
    public Result<IPage<ArticleTagResponse>> getTagList(ArticleTagQueryRequest queryRequest) {
        log.info("查询标签列表: {}", queryRequest);
        try {
            IPage<ArticleTagResponse> pageResult = tagManagementService.getTagPage(queryRequest);
            return Result.success(pageResult);
        } catch (Exception e) {
            log.error("查询标签列表失败", e);
            return Result.error("查询标签列表失败：" + e.getMessage());
        }
    }
    /**
     * 获取标签详情
     */
    @GetMapping("/{tagId}")
    public Result<ArticleTagResponse> getTagDetail(@PathVariable @NotNull Long tagId) {
        log.info("获取标签详情: tagId={}", tagId);
        try {
            ArticleTagResponse detail = tagManagementService.getTagDetailNew(tagId);
            if (detail == null) {
                return Result.error("标签不存在");
            }
            return Result.success(detail);
        } catch (Exception e) {
            log.error("获取标签详情失败", e);
            return Result.error("获取标签详情失败：" + e.getMessage());
        }
    }

    /**
     * 创建标签
     */
    @PostMapping
    @SaCheckRole("admin")
    public Result<Void> createTag(@RequestBody @Valid ArticleTagCreateRequest createRequest) {
        log.info("创建标签: {}", createRequest);
        try {
            boolean success = tagManagementService.createTag(createRequest);
            if (success) {
                return Result.success("创建标签成功");
            } else {
                return Result.error("创建标签失败");
            }
        } catch (Exception e) {
            log.error("创建标签失败", e);
            return Result.error("创建标签失败：" + e.getMessage());
        }
    }

    /**
     * 更新标签
     */
    @PutMapping("/{tagId}")
    @SaCheckRole("admin")
    public Result<Void> updateTag(@PathVariable @NotNull Long tagId,
                                  @RequestBody @Valid ArticleTagUpdateRequest updateRequest) {
        log.info("更新标签: tagId={}, updateRequest={}", tagId, updateRequest);
        try {
            updateRequest.setId(tagId);
            boolean success = tagManagementService.updateTag(updateRequest);
            if (success) {
                return Result.success("更新标签成功");
            } else {
                return Result.error("更新标签失败");
            }
        } catch (Exception e) {
            log.error("更新标签失败", e);
            return Result.error("更新标签失败：" + e.getMessage());
        }
    }

    /**
     * 删除标签
     */
    @DeleteMapping("/{tagId}")
    @SaCheckRole("admin")
    public Result<Void> deleteTag(@PathVariable @NotNull Long tagId) {
        log.info("删除标签: tagId={}", tagId);
        try {
            boolean success = tagManagementService.deleteTag(tagId);
            if (success) {
                return Result.success("删除标签成功");
            } else {
                return Result.error("删除标签失败");
            }
        } catch (Exception e) {
            log.error("删除标签失败", e);
            return Result.error("删除标签失败：" + e.getMessage());
        }
    }

    /**
     * 批量操作标签
     */
    @PostMapping("/batch")
    @SaCheckRole("admin")
    public Result<String> batchOperation(@RequestBody @Valid TagBatchOperationRequest batchRequest) {
        log.info("批量操作标签: {}", batchRequest);
        try {
            String result = tagManagementService.batchOperation(batchRequest);
            return Result.success(result);
        } catch (Exception e) {
            log.error("批量操作标签失败", e);
            return Result.error("批量操作标签失败：" + e.getMessage());
        }
    }

    /**
     * 获取启用的标签列表（用于下拉选择）
     */
    @GetMapping("/enabled")
    public Result<List<ArticleTag>> getEnabledTags() {
        log.info("获取启用的标签列表");
        try {
            List<ArticleTag> enabledTags = tagManagementService.getEnabledTags();
            return Result.success(enabledTags);
        } catch (Exception e) {
            log.error("获取启用标签列表失败", e);
            return Result.error("获取启用标签列表失败：" + e.getMessage());
        }
    }

    /**
     * 搜索标签（用于自动完成）
     */
    @GetMapping("/search")
    public Result<List<ArticleTag>> searchTags(@RequestParam String keyword,
                                               @RequestParam(defaultValue = "10") int limit) {
        log.info("搜索标签: keyword={}, limit={}", keyword, limit);
        try {
            List<ArticleTag> tags = tagManagementService.searchTags(keyword, limit);
            return Result.success(tags);
        } catch (Exception e) {
            log.error("搜索标签失败", e);
            return Result.error("搜索标签失败：" + e.getMessage());
        }
    }

    /**
     * 获取热门标签
     */
    @GetMapping("/hot")
    public Result<List<ArticleTag>> getHotTags(@RequestParam(defaultValue = "20") int limit) {
        log.info("获取热门标签: limit={}", limit);
        try {
            List<ArticleTag> hotTags = articleTagRelationService.getHotTags(limit);
            return Result.success(hotTags);
        } catch (Exception e) {
            log.error("获取热门标签失败", e);
            return Result.error("获取热门标签失败：" + e.getMessage());
        }
    }

    /**
     * 获取标签统计信息
     */
    @GetMapping("/statistics")
    @SaCheckRole("admin")
    public Result<Map<String, Object>> getTagStatistics() {
        log.info("获取标签统计信息");
        try {
            Map<String, Object> statistics = tagManagementService.getTagStatistics();
            return Result.success(statistics);
        } catch (Exception e) {
            log.error("获取标签统计信息失败", e);
            return Result.error("获取标签统计信息失败：" + e.getMessage());
        }
    }

    /**
     * 根据标签查询文章
     */
    @GetMapping("/{tagId}/articles")
    public Result<List<Long>> getArticlesByTag(@PathVariable @NotNull Long tagId) {
        log.info("根据标签查询文章: tagId={}", tagId);
        try {
            List<Long> articleIds = articleTagRelationService.getArticleIdsByTagId(tagId);
            return Result.success(articleIds);
        } catch (Exception e) {
            log.error("根据标签查询文章失败", e);
            return Result.error("根据标签查询文章失败：" + e.getMessage());
        }
    }

    /**
     * 检查标签名称是否存在
     */
    @GetMapping("/check-name")
    public Result<Boolean> checkTagName(@RequestParam String name,
                                        @RequestParam(required = false) Long excludeId) {
        log.info("检查标签名称: name={}, excludeId={}", name, excludeId);
        try {
            boolean exists = tagManagementService.isTagNameExists(name, excludeId);
            return Result.success(exists);
        } catch (Exception e) {
            log.error("检查标签名称失败", e);
            return Result.error("检查标签名称失败：" + e.getMessage());
        }
    }

    /**
     * 重新计算标签使用次数
     */
    @PostMapping("/{tagId}/recalculate-use-count")
    @SaCheckRole("admin")
    public Result<Void> recalculateTagUseCount(@PathVariable @NotNull Long tagId) {
        log.info("重新计算标签使用次数: tagId={}", tagId);
        try {
            boolean success = articleTagRelationService.recalculateTagUseCount(tagId);
            if (success) {
                return Result.success("重新计算标签使用次数成功");
            } else {
                return Result.error("重新计算标签使用次数失败");
            }
        } catch (Exception e) {
            log.error("重新计算标签使用次数失败", e);
            return Result.error("重新计算标签使用次数失败：" + e.getMessage());
        }
    }

    /**
     * 批量重新计算所有标签使用次数
     */
    @PostMapping("/recalculate-all-use-counts")
    @SaCheckRole("admin")
    public Result<String> recalculateAllTagUseCounts() {
        log.info("批量重新计算所有标签使用次数");
        try {
            int count = articleTagRelationService.recalculateAllTagUseCounts();
            return Result.success("成功重新计算了 " + count + " 个标签的使用次数");
        } catch (Exception e) {
            log.error("批量重新计算标签使用次数失败", e);
            return Result.error("批量重新计算标签使用次数失败：" + e.getMessage());
        }
    }

    /**
     * 获取所有标签列表（用于用户端文章发布）
     * 无需分页，返回所有标签按创建时间倒序排列
     */
    @GetMapping("/all-tags")
    public Result<List<ArticleTag>> getAllTags() {
        log.info("用户端获取所有标签列表");
        try {
            List<ArticleTag> allTags = tagManagementService.getAllTags();
            return Result.success("获取所有标签成功", allTags);
        } catch (Exception e) {
            log.error("获取所有标签列表失败", e);
            return Result.error("获取所有标签列表失败：" + e.getMessage());
        }
    }
}